<template>
    <!-- 搜索与操作区 -->
    <div style="display: flex">
        <el-button type="primary" style="margin-right: 15px  " @click="addItem">新增</el-button>
        <el-input v-model="search" placeholder="请输入视频名称"
            style="width: 200px;height: 33px;margin-right: 15px;font-size: 15px;" clearable />
        <el-select v-model="searchCourseId" placeholder="请选择课程名称" filterable clearable
            style="width: 200px;height: 33px;margin-right: 15px;font-size: 15px">
            <el-option v-for="item in courseOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
        </el-select>
        <el-button type="primary" style="color: #fff;font-size: 12px;background-color: #1890ff;" @click="load">搜索
        </el-button>
    </div>

    <!-- 视频列表表格 -->
    <el-table :data="tableData" :row-style="{ height: '77px' }"
        style="width: calc(100vw - 240px);height: 75vh;margin-top: 20px;font-size: 15px;" border>
        <!-- 表格列 -->
        <el-table-column prop="name" label="视频名称" width="auto" align="center" />
        <el-table-column prop="courseName" label="课程名称" width="auto" align="center" />
        <el-table-column prop="teachName" label="培训讲师名称" width="auto" align="center" />
        <el-table-column prop="code" label="二维码" align="center" width="180">
            <template v-slot="scope">
                <div @click="openPreview(scope.row.code)" style="cursor: pointer;">
                    <el-image style="width: 100px; height: 100px" :src="scope.row.code"></el-image>
                </div>
            </template>
        </el-table-column>
        <el-table-column prop="time" label="时长" width="auto" align="center">
            <template v-slot="scope">
                {{ formatTime(scope.row.time) }}
            </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="200" align="center">
            <template v-slot="scope">
                <div>
                    <el-button icon="Edit" size="small" type="primary" @click="editItem(scope.row)">编辑</el-button>
                    <el-button icon="View" size="small" type="success" @click="videoLinePlay(scope.row)">播放</el-button>
                </div>
                <div>
                    <el-button icon="Download" size="small" type="warning"
                        @click="download(scope.row.url)">下载</el-button>
                    <el-button icon="Delete" size="small" type="danger" @click="deleteItem(scope.row.id)">删除</el-button>
                </div>
            </template>
        </el-table-column>
    </el-table>

    <!--      分页-->
    <div style="margin-top: 10px">
        <el-pagination :current-page="currentPage" :page-size="pageSize" :page-sizes="[10, 20, 30, 50]"
            layout="total, sizes, prev, pager, next, jumper" :total="total" :background="true"
            @size-change="handleSizeChange" @current-change="handleCurrentChange" />
    </div>

    <el-dialog :close-on-click-modal="false" title="视频操作" v-model="dialogVisible" width="560" @close="reset('form')">
        <el-form label-position="top" :inline="true" :model="form" ref="form" :rules="rules">
            <!--输入用户名-->
            <el-form-item label="视频名称" prop="name">
                <el-input placeholder="请输入视频名称" v-model="form.name" autocomplete="off" clearable></el-input>
            </el-form-item>
            <el-form-item label="培训讲师名称" prop="teachId" filterable clearable>
                <el-select v-model="form.teachId" clearable placeholder="请选择培训讲师名称" style="width: 185px">
                    <el-option v-for="item in teachOptions" :key="item.id" :label="item.username" :value="item.id" />
                </el-select>
            </el-form-item>
            <el-form-item label="课程名称" prop="courseId" filterable clearable>
                <el-select v-model="form.courseId" clearable placeholder="请选择课程名称" style="width: 185px">
                    <el-option v-for="item in courseOptions" :key="item.id" :label="item.name" :value="item.id" />
                </el-select>
            </el-form-item>
            <el-form-item label="上传文件" prop="url">
                <el-upload :before-upload="checkFileType" class="avatar-uploader" :action="'/api/files/upload'"
                    :on-success="photoHandleSuccess" :on-error="photoHandleError" :show-file-list="false">
                    <el-button size="center" type="primary">上传</el-button>
                    <el-button size="small" type="danger" v-if="form.url" @click="deleteImage">删除</el-button>
                </el-upload>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="reset('form')">取 消</el-button>
            <el-button type="primary" @click="submitForm('form')">确 定</el-button>
        </div>
    </el-dialog>

    <el-dialog :close-on-click-modal="false" v-model="dialogVideoVisible" title="视频播放" @close="closedialogVisible">
        <div class="video-monitor-wrapper">
            <video class="videoPlayer" :src="videoUrl" controls style="width: 100%;height: 100%" @play="playVideo"
                ref="vueMiniPlayer" type="video/mp4">
            </video>
        </div>
    </el-dialog>

    <ImagePreview ref="preview" :imageUrl="currentPreviewImage" />
</template>

<script>
import { serverIp } from "~/utils/config.js"
import request from "~/utils/request.js";
import ImagePreview from '~/pages/ImagePreview.vue';

export default {
    components: {
        ImagePreview
    },
    data() {
        return {
            dialogVideoVisible: false,
            dialogVisible: false,
            form: {},
            courseOptions: [],
            teachOptions: [],
            videoUrl: "",
            tableData: [],
            search: '',
            searchCourseId: '',
            currentPage: 1,
            pageSize: 10,
            total: 0,
            rules: {
                name: [
                    { required: true, message: '请输入视频名称', trigger: 'blur' },
                ],
                teachId: [
                    { required: true, message: '请选择培训讲师名称', trigger: 'blur' },
                ],
                courseId: [
                    { required: true, message: '请选择课程名称', trigger: 'blur' },
                ]
            },
            currentPreviewImage: "",
        }
    },
    async created() {
        await this.getCourseOptions()
        await this.getTeacherOptions()
        await this.load()
    },
    methods: {
        async load() {
            if (this.$route.query.courseId === undefined && this.searchCourseId === undefined) {
                this.searchCourseId = ''
            } else if (this.$route.query.courseId !== undefined) {
                this.searchCourseId = Number(this.$route.query.courseId)
            }
            request.get("/period/page?pageNum=" + this.currentPage + "&pageSize=" + this.pageSize + "&courseId=" + this.searchCourseId + "&name=" + this.search).then(res => {
                if (res.code === '200') {
                    this.tableData = res.data.records;
                    this.total = res.data.total;
                } else {
                    ElMessage.error("错误" + res.msg)
                }
            })
        },
        async getCourseOptions() {
            request.get("/course/all").then(res => {
                this.courseOptions = res.data
            })
        },
        async getTeacherOptions() {
            request.get("/user/selectTeachers").then(res => {
                this.teachOptions = res.data
            })
        },
        formatTime(seconds) {
            if (seconds == null || seconds === '' || isNaN(seconds)) return '00:00';
            seconds = parseInt(seconds);
            const hours = Math.floor(seconds / 3600);
            const minutes = Math.floor((seconds % 3600) / 60);
            const secs = seconds % 60;

            if (hours > 0) {
                return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
            } else {
                return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
            }
        },
        videoLinePlay(row) {
            this.videoUrl = serverIp + row.url;
            this.dialogVideoVisible = true;
        },
        download(url) {
            const fileName = `${encodeURIComponent(url.split('/').pop())}`
            window.open(serverIp + "/api/files/download/" + fileName)
        },
        editItem(item) {
            Object.assign(this.form, item)
            this.dialogVisible = true
        },
        addItem() {
            this.dialogVisible = true;
        },
        // 删除
        deleteItem(scope) {
            this.$confirm('是否确定删除?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                request.get("/period/delete/" + scope).then(res => {
                    if (res.code === '200') {
                        this.$message.success("成功")
                        this.load()
                    } else {
                        this.$message.error(res.msg)
                    }
                })
            });
        },
        // 提交
        submitForm(val) {
            this.$refs[val].validate((valid) => {
                if (valid) {
                    request.post("/period/edit", this.form).then(res => {
                        if (res.code === '200') {
                            this.$message({
                                message: "成功",
                                type: "success"
                            })
                            this.load()
                            this.reset(val)
                        } else {
                            this.$message.error(res.msg)
                        }
                    })
                }
            })
        },
        // 取消
        reset(val) {
            this.dialogVisible = false;
            this.form = {};
            this.$refs[val].resetFields();
        },
        handleCurrentChange(item) {
            // 改变当前页码触发
            this.currentPage = item
            this.load()
        },
        handleSizeChange(item) {   // 改变当前每页的个数触发
            this.pageSize = item
            this.load()
        },
        // 监听vidoe播放的事件
        playVideo() {
            this.$store.commit("changePlayState", false);
        },
        closedialogVisible() {
            this.$refs.vueMiniPlayer.pause();//暂停
        },
        checkFileType(file) {
            const fileName = file.name
            const fileType = fileName.substring(fileName.lastIndexOf('.'))
            if (
                fileType === '.mp4'
            ) {
                // 不处理
            } else {
                this.$message.error(
                    '不是正确的格式文件,请上传正确的文件类型'
                )
                return false
            }
        },
        photoHandleError() {
            this.$message.error("上传文件失败")
        },
        deleteImage() {
            this.form.url = '';
            this.$message.success('删除成功');
        },
        base64ImgtoFile(base64Data, filename = 'thumbnail.jpg') {
            const arr = base64Data.split(',')
            const mime = arr[0].match(/:(.*?);/)[1]
            const bstr = atob(arr[1])
            let n = bstr.length
            const u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            return new File([u8arr], filename, { type: mime })
        },

        async captureThumbnail() {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            const videoElement = document.createElement('video');
            videoElement.crossOrigin = 'anonymous';
            videoElement.src = serverIp + this.form.url;

            try {
                await new Promise((resolve, reject) => {
                    // 新增：监听元数据加载以获取时长
                    videoElement.addEventListener('loadedmetadata', () => {
                        // 获取时长并保存到表单
                        this.form.time = Math.round(videoElement.duration);
                        videoElement.currentTime = 1; // 跳转到第1秒
                    });

                    videoElement.addEventListener('seeked', async () => {
                        canvas.width = videoElement.videoWidth;
                        canvas.height = videoElement.videoHeight;
                        ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
                        const thumbnailUrl = canvas.toDataURL('image/jpeg');

                        try {
                            const thumbnailPath = await this.uploadImage(thumbnailUrl);
                            this.form.thumbnailUrl = thumbnailPath;
                        } catch (error) {
                            console.error('缩略图上传失败:', error);
                        }
                        resolve();
                    });

                    videoElement.addEventListener('error', reject);
                });
            } catch (error) {
                console.error('视频加载失败:', error);
            }
        },

        async uploadImage(base64Img) {
            const imgFile = this.base64ImgtoFile(base64Img)
            const formData = new FormData()
            formData.append('file', imgFile)

            try {
                const res = await request.post("/files/upload", formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                })

                if (res !== '') {
                    this.$message.success('缩略图上传成功')
                    return `/api/file/download/${res}` // 根据实际返回结构调整
                } else {
                    throw new Error(res)
                }
            } catch (error) {
                this.$message.error('缩略图上传失败: ' + error.message)
                throw error
            }
        },

        photoHandleSuccess(response) {
            this.form.url = `/api/file/download/${response}`
            this.$nextTick(() => {
                this.captureThumbnail() // 确保DOM更新后执行
            })
            this.$message.success('视频上传成功')
        },

        handleClear() {
            this.searchCourseId = ''
            this.$route.query.courseId = ''
        },

        openPreview(imageUrl) {
            if (!imageUrl) return;
            this.currentPreviewImage = imageUrl;
            this.$nextTick(() => {
                this.$refs.preview.open();
            });
        }
    }
}
</script>

<style scoped>
.video-monitor-wrapper {
    width: 80%;
    height: 70%;
    text-align: center;
    margin: 25px auto 15px auto;
}
</style>
